package com.siecom.transport.bluetooth;

import android.os.SystemClock;
import android.util.Log;
import android.widget.Toast;

import com.ft16.gpio;
import com.google.protobuf.InvalidProtocolBufferException;
import com.siecom.hostservice.MainActivity;
import com.siecom.hostservice.ScreenService;
import com.siecom.nativelibs.NativeFunction;
import com.siecom.nativelibs.SerialPort;
import com.siecom.proto.Message;
import com.siecom.tool.ByteTool;
import com.siecom.tool.LogUtil;
import com.siecom.tool.SingletonThreadPool;
import com.siecom.transport.CommServer;
import com.siecom.transport.Distribution;
import com.siecom.transport.handler.ServiceHandler;
import com.siecom.transport.serialport.SerialServer;
import com.siecom.transport.usbport.UsbServer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class IosSerialServer extends CommServer {

    private static final String TAG = IosSerialServer.class.getSimpleName();
    private HashMap<Integer, ServiceHandler> handlerMap = Distribution.handlerMap;
    private static final String ET_PORT = "/dev/ttyXRM0";

    public static int BandRate = 230400;  //230400
    private SerialPort mSerialPort;
    public OutputStream mOutputStream;
    public InputStream mInputStream;
    private static final int perLen = 30;
    private byte[]       mBytes        = new byte[1024*11];
    public static ExecutorService executorService = Executors.newSingleThreadExecutor();
    public IosSerialServer() {
        gpio.gpio_control(124,1);//BT_EN
        gpio.gpio_control(63,1);//CMD_DATA_SWITCH(DATA MODE)
        gpio.gpio_control(129,1);//BT_LowPower(Exit LowPower)

        try {
            mSerialPort = new SerialPort(new File(ET_PORT),BandRate,0);
            mInputStream =  mSerialPort.getInputStream();
            mOutputStream = mSerialPort.getOutputStream();
            LogUtil.e(TAG,"串口打开成功：mInputStream=" + mInputStream + "--mOutputStream=" + mOutputStream + "----" + BandRate);


        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    int totalLen = 0;
    ArrayList mByteArray = new ArrayList<Byte>();
    Message.siecomproto msg;
    byte[] head = new byte[1];
    public void listenFromPort(){
        Runnable mrunnable = new Runnable() {
            @Override
            public void run() {

                synchronized (this) {

                    int i = 0;
                    int len = 0;
                    while (!isInterrupted) {

                        try {
                            if(!MainActivity.mScreenOn){
                                totalLen = 0;
                                mByteArray.clear();
                                while (mInputStream.available() > 0){
                                    mInputStream.read();
                                }
                                continue;
                            }

                            len = mInputStream.available();
                            if(len > 0){

                                totalLen += len;
                                LogUtil.e(TAG,"接收到的数据len：" + len + "----totalLen == " + totalLen);

                                byte[] b = new byte[len];
                                mInputStream.read(b,0,len);
                                if ( len == 4 && b[0] == 0x4F && b[1]== 0x4B){
                                    LogUtil.e(TAG,"收到了OK！！！！" );
                                    totalLen = 0;
                                    mByteArray.clear();
                                    continue;
                                }
                                if ( len == 3 && b[0] == 0x45 && b[1]== 0x52 && b[2] == 0x52){
                                    LogUtil.e(TAG,"收到了ERR！！！！" );
                                    totalLen = 0;
                                    mByteArray.clear();
                                    continue;
                                }

                                LogUtil.e(TAG,"收到的数据：" + ByteTool.byte2hex(b));
                                for(int j = 0; j< len;j++){
                                    mByteArray.add(b[j]);
                                }
                                byte[] sendByte = new byte[totalLen];
                                for(int m = 0;m < totalLen; m++){
                                    sendByte[m] = (byte)mByteArray.get(m);
                                }
//                                LogUtil.e(TAG,"接收到的数据byte：" + ByteTool.byte2hex(sendByte));

                                if(sendByte[0] == 0x02){
                                    int sendLen = (sendByte[1]&0xFF)*256 + (sendByte[2]&0xFF);
//                                        LogUtil.e(TAG," byte sendLen=" + sendLen);

                                    if((sendLen + 5) == totalLen){
                                        byte[]  fina = new byte[sendLen];
                                        System.arraycopy(sendByte,3,fina,0,sendLen);
                                        Message.siecomproto msg = Message.siecomproto.parseFrom(fina);
                                        int module = msg.getModule();
//                                          Log.e(TAG, "USB cmd==" + msg.getCmd());
                                        if (handlerMap.containsKey(module)) {
                                            LogUtil.e(TAG,"接收到的数据msg：" + msg.toString() + "--length==" + sendByte.length);
                                            ServiceHandler handler = handlerMap.get(module);
                                            handler.onReceive(IosSerialServer.this, msg,"");
                                        }
                                        if((sendLen + 5) <= totalLen){
                                            totalLen = 0;
                                            mByteArray.clear();
                                        }

                                    }
                                    //当接收的总数据过大时
                                    if(totalLen > (sendLen + 5)){
                                        LogUtil.e(TAG,"异常--数据过大了！！！");
//                                            totalLen = 0;
//                                            mByteArray.clear();
                                    }

                                }


                            }

                        } catch (InvalidProtocolBufferException ex) {
                            ex.printStackTrace();
                            LogUtil.e(TAG,"接收消息解析异常" + ex.getMessage());

                        } catch (IOException e) {
                            e.printStackTrace();
                            LogUtil.e(TAG,"IOException :" + e.getMessage());
//                        observableEmitter.onError(e);
                            totalLen = 0;
                            mByteArray.clear();
                            SystemClock.sleep(3);
                            break;
                        }catch (IndexOutOfBoundsException e){
                            totalLen = 0;
                            mByteArray.clear();
                            break;
                        }
                        SystemClock.sleep(10);
                    }

                }

            }

        };
        SingletonThreadPool.getInstance().submit(mrunnable);

        //改名字：
        try {
            String name =  BlueServer.getBlueName() + "i";
            Thread.sleep(1000);
            mOutputStream.write(("AT+LENAME="+ name +"\r\n").getBytes());
            Toast.makeText(MainActivity.context,""+name,Toast.LENGTH_SHORT).show();
            LogUtil.e(TAG,"改的名字：" + name);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }

    }
    byte[] crcOut = new byte[2];
    @Override
    public void sendToRemote(Message.siecomproto msg) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {

                synchronized (this){
                    try {
                        LogUtil.e(TAG,"发送数据："+ msg.toString());

                        byte[] b = msg.toByteArray();
//                        LogUtil.e(TAG,"发送数据："+ ByteTool.byte2hex(b));
                        int len = b.length;
                        int allLen = len + 5;
                        byte[] allData = new byte[allLen];
                        allData[0] = 0x02;
                        allData[1] = (byte)(len / 256);
                        allData[2] = (byte)(len % 256);
                        System.arraycopy(b,0,allData,3,len);
//                        LogUtil.e(TAG,"带头和长度："+ ByteTool.byte2hex(allData));
                        NativeFunction.Crc16CCITT2(allData,len+3,0,crcOut);
//                        LogUtil.e(TAG,"crcOut=="+ ByteTool.byte2hex(crcOut));
                        allData[len + 3] = crcOut[0];
                        allData[len + 4] = crcOut[1];
                        LogUtil.e(TAG,"带头和长度："+ ByteTool.byte2hex(allData));
                        LogUtil.e(TAG,"总长度长度："+ allData.length);
                        int offset = 0;
                        long start = System.currentTimeMillis();
                        while (allLen > 0){

//                            LogUtil.e(TAG,"allLen剩余len===" + allLen);
                            if(allLen < perLen){
                                mOutputStream.write(allData,offset,allLen);
                                long end = System.currentTimeMillis();
                                LogUtil.e(TAG,"发送剩余===" + allLen + "用时：" + (end - start));

                            }else {
                                mOutputStream.write(allData,offset,perLen);
//                                    LogUtil.e(TAG,"发送len"+perLen+"剩余===" + allLen);
                            }
                            allLen -= perLen;
                            offset += perLen;
                            Thread.sleep(10);

                        }
                        while (mInputStream.available() > 0){
                            mInputStream.read();
                        }
                        totalLen = 0;
                        mByteArray.clear();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                }

        };

            executorService.submit(runnable);
    }
}
